package com.xinshujia.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.mqtt.core.MqttPahoClientFactory;
import org.springframework.integration.mqtt.outbound.MqttPahoMessageHandler;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.MessageHandler;

import java.util.UUID;

import static com.xinshujia.config.MqttConstant.CHANNEL_NAME_OUT;

/**
 * *************************************
 * *   @author: 野狼上校               **
 * *   @since: 2024-07-25 16:59       **
 * *   @version: 1.0                  **
 * *************************************
 * <p>
 * 发布者配置
 */
@Configuration
public class MqttPublishConfig {
    // 客户端ID
    @Value("${spring.mqtt.clientId}")
    private String clientId;
    // 发布主题
    @Value("${spring.mqtt.topic.publish}")
    private String publishTopic;

    // MQTT客户端的连接工厂
    private final MqttPahoClientFactory mqttClientFactory;

    public MqttPublishConfig(MqttPahoClientFactory mqttClientFactory) {
        System.out.println("MqttPublishConfig:MqttPublishConfig");
        this.mqttClientFactory = mqttClientFactory;
    }

    /**
     * MQTT信息通道 - 出站（生产者）
     */
    @Bean(name = CHANNEL_NAME_OUT)
    public MessageChannel mqttOutboundChannel() {
        System.out.println("MqttPublishConfig: MessageChannel");
        return new DirectChannel();
    }


    /**
     * MQTT消息处理器 - 出站（生产者）
     */
    @Bean
    @ServiceActivator(inputChannel = CHANNEL_NAME_OUT)
    public MessageHandler mqttOutbound() {
        System.out.println("MessageChannel: mqttOutbound");
        MqttPahoMessageHandler messageHandler = new MqttPahoMessageHandler(clientId + UUID.randomUUID().toString().substring(0,8), mqttClientFactory);
        //设置默认的qos级别
        messageHandler.setDefaultQos(1);
        //保留标志的默认值。如果没有mqtt_retained找到标题，则使用它。如果提供了自定义，则不使用它converter。这里不启用
        messageHandler.setDefaultRetained(false);
        //设置发布的主题
        messageHandler.setDefaultTopic(publishTopic);
        //当 时true，调用者不会阻塞。相反，它在发送消息时等待传递确认。默认值为false（在确认交付之前发送阻止）。
        messageHandler.setAsync(true);
        //当 async 和 async-events 都为 true 时，会发出 MqttMessageSentEvent（请参阅事件）。
        // 它包含消息、主题、客户端库生成的messageId、clientId和clientInstance（每次连接客户端时递增）。
        // 当客户端库确认交付时，会发出 MqttMessageDeliveredEvent。它包含 messageId、clientId 和 clientInstance，使传递与发送相关联。
        // 任何 ApplicationListener 或事件入站通道适配器都可以接收这些事件。
        // 请注意，有可能在 MqttMessageSentEvent 之前接收到 MqttMessageDeliveredEvent。默认值为false。
        messageHandler.setAsyncEvents(false);
        return messageHandler;
    }
}
